package com.huiw.archives.modules.sys.dao.impl;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.huiw.archives.common.utils.database.Order;
import com.huiw.archives.common.utils.database.PageParams;
import com.huiw.archives.modules.sys.dao.CommonDao;

/**
 * hibernate查询对象通用类
 * 
 * @author YC
 *
 */
@Repository("CommonDao")
public class CommonDaoImpl implements CommonDao {

	@Autowired
	public SessionFactory sessionFactory;

	public Session getCurrentSession() {
		return this.sessionFactory.getCurrentSession();
	}

	Session s;

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: load
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param id
	 * @return
	 * @see com.yang.webhook.modules.dao.CommonDao#load(java.lang.Integer)
	 */
	@Override
	public Object load(String id, Object object) {
		return this.getCurrentSession().load(object.getClass(), id);
	}

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: get
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param id
	 * @return
	 * @see com.yang.webhook.modules.dao.CommonDao#get(java.lang.Integer)
	 */
	@Override
	public Object get(String id, Object object) {
		return this.getCurrentSession().get(object.getClass(), id);
	}

	/**
	 * 刘超 2017年7月11日 上午11:25:04
	 * <p>
	 * Title: get
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param id
	 * @return
	 * @see com.yang.webhook.modules.dao.CommonDao#get(java.lang.Integer)
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> queryByHql(String hql) throws Exception{
		try {
			Query query = this.getCurrentSession().createQuery(hql);
			return query.list();
		} catch (Exception e) {
			System.out.println("query方法异常：" + e.getMessage());
			return null;
		}

	}

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: findAll
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @return
	 * @see com.yang.webhook.modules.dao.CommonDao#findAll()
	 */
	@Override
	public List<Object> findAll(Object object) {
		@SuppressWarnings("unchecked")
		List<Object> list = this.sessionFactory.getCurrentSession().createCriteria(object.getClass()).list();
		return list;
	}

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: persist
	 * </p>
	 * <p>
	 * Description:persist如果在transaction之外调用，不会导致insert语句的立即执行，
	 * 而是在flush时执行insert语句。 persist如果在transaction之内调用，会导致insert语句的立即执行
	 * ，适用于被扩展的Session上下文的长期运行的会话中
	 * </p>
	 * 
	 * @param entity
	 * @see com.yang.webhook.modules.dao.CommonDao#persist(java.lang.Object)
	 */
	@Override
	public void persist(Object entity) {
		this.getCurrentSession().persist(entity);
	}

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: delete
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 * @see com.yang.webhook.modules.dao.CommonDao#delete(java.lang.Integer)
	 */
	@Override
	public boolean deletebatch(Object object, String[] ids) throws Exception {
		boolean flag = false;
		for (String id : ids) {
			Object obj = query(id, object);

			flag = obj == null ? false : delete(query(id, object));
		}
		return flag;
	}

	/**
	 * YC 2017年6月29日 上午11:25:04
	 * <p>
	 * Title: 冲洗session缓存
	 * </p>
	 * <p>
	 * Description:将session的缓存中的数据与数据库同步
	 * </p>
	 * 
	 * @see com.yang.webhook.modules.dao.CommonDao#flush()
	 */
	@Override
	public void flush() {
		this.getCurrentSession().flush();
	}

	/**
	 * 数据层通用类 方法： 1.通过id删除（id,对象），返回boolean； 2.通过id查询（id,对象），返回object；
	 * 3.保存（对象），返回boolean； 4.修改（对象），返回boolean； 5.取等条件查询（对象类，字段，值），返回集合；
	 * 6.获取所有记录，返回集合； 7.降序查询（对象类,数据库字段）; 8.升序查询（对象类,数据库字段）
	 * 
	 */

	// 1.删除
	@Override
	public boolean delete(Object object) {
		try {
			s = this.sessionFactory.getCurrentSession();
			s.delete(object);
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	// 2.通过id查询
	@Override
	public Object query(String id, Object object) throws Exception {

		Criteria c = this.getCurrentSession().createCriteria(object.getClass());
		c.add(Restrictions.eq("id", id));
		return c.uniqueResult();
	}

	// 3.保存
	@Override
	public boolean save(Object object) {

		try {
			s = this.sessionFactory.getCurrentSession();
			s.persist(object);
			// s.flush();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	// 4.修改
	@Override
	public boolean update(Object object) {
		try {
			s = this.sessionFactory.getCurrentSession();
			s.update(object);
			s.flush();
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	@Override
	public boolean saveOrUpdate(Object object) {
		try {
			this.getCurrentSession().saveOrUpdate(object);

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	// 5.取等条件查询（对象类,数据库字段，条件值）
	// Restrictions.eq 等于
	// Restrictions.allEq 使用Map，使用key/value进行多个等于的比对
	// Restrictions.gt 大于 >
	// Restrictions.ge 大于等于 >=
	// Restrictions.lt 小于 <
	// Restrictions.le 小于等于 <=
	// Restrictions.between 对应SQL的BETWEEN子句
	// Restrictions.like 对应SQL的LIKE子句
	// Restrictions.in 对应SQL的in子句
	// Restrictions.and and关系
	// Restrictions.or or关系
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> query(Object object, Object[] key, Object[] value) {
		try {
			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			for (int i = 0; i < key.length; i++) {
				c.add(Restrictions.eq(key[i].toString(), value[i]));
			}
			return c.list();
		} catch (Exception e) {
			return null;
		}
	}

	// 6.获取所有记录，返回集合；
	@SuppressWarnings("unchecked")
	@Override
	public List<Object> query(Object object) {

		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());

			return c.list();
		} catch (Exception e) {
			return null;
		}
	}

	// 7.降序查询（对象类,数据库字段）
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> queryOrderDesc(Object object, String keys, int maxResults) {

		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			c.addOrder(Order.desc(keys));
			c.setMaxResults(maxResults);
			return c.list();
		} catch (Exception e) {
			return null;
		}

	}

	// 8.升序查询（对象类,数据库字段）
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> queryOrderAsc(Object object, String keys, int maxResults) {

		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			c.addOrder(Order.asc(keys));
			c.setMaxResults(maxResults);

			return c.list();
		} catch (Exception e) {
			return null;
		}

	}

	// 9.获取最后一条记录的id（对象类）
	@Override
	public Object queryLastRecordId(Object object) {

		try {
			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			c.addOrder(Order.desc("id"));
			c.setMaxResults(1);

			return c.uniqueResult();
		} catch (Exception e) {
			return null;
		}

	}

	// 10.分页查询记录，返回集合；
	@SuppressWarnings("unchecked")
	/*
	 * query Object object数据表 int curPage,当前页数 int max,每页条数 String keys,字段
	 * String values,字段值
	 */
	@Override
	public List<Object> query(Object object, int curPage, int max, String keys, String values) {

		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			if (!values.equals("")) {
				c.add(Restrictions.eq(keys, values));
			}
			c.setFirstResult(curPage * max);
			c.setMaxResults(max);

			return c.list();
		} catch (Exception e) {
			return null;
		}

	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Object> query(Object object, int curPage, int max, Object[] key, Object[] value) {
		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			for (int i = 0; i < key.length; i++) {
				if (!value[i].equals("")) {
					c.add(Restrictions.eq(key[i].toString(), value[i]));
				}
			}
			// System.out.println("123");
			// Query query = this.getCurrentSession().createQuery("from
			// WisOrgGroupperson where "+key[0]+"='"+value[0]+"'");
			c.setFirstResult(curPage * max);
			c.setMaxResults(max);

			return c.list();
		} catch (Exception e) {
			return null;
		}

	}

	// 11.获取该表某类型记录总条数{object表，keys字段，values字段对应值}
	@Override
	public double queryRecordNum(Object object, String keys, Object values) {
		String rows = null;
		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			if (!keys.isEmpty())
				c.add(Restrictions.eq(keys, values));
			// Projections.rowCount() 来取得总记录数
			rows = c.setProjection(Projections.rowCount()).uniqueResult().toString();
			return Double.parseDouble(rows);
		} catch (Exception e) {
			return 0;
		}

	}

	// 获取该表某类型记录总条数{object表，keys字段，values字段对应值,operator运算符}
	@Override
	public double queryRecordNum(Object object, String key, Object values, String operator) {

		String rows = null;
		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());
			if (!key.isEmpty()) {
				if (values != null) {

					// =
					if ("=".equals(operator))
						c.add(Restrictions.eq(key,
								(values instanceof Integer) ? (Integer.parseInt(values.toString())) : values));
					// ＞
					if (">".equals(operator))
						c.add(Restrictions.gt(key,
								(values instanceof Integer) ? (Integer.parseInt(values.toString())) : values));
					// ＞＝
					if (">=".equals(operator))
						c.add(Restrictions.ge(key,
								(values instanceof Integer) ? (Integer.parseInt(values.toString())) : values));
					// ＜
					if ("<".equals(operator))
						c.add(Restrictions.lt(key,
								(values instanceof Integer) ? (Integer.parseInt(values.toString())) : values));
					// ＜＝
					if ("<=".equals(operator))
						c.add(Restrictions.le(key,
								(values instanceof Integer) ? (Integer.parseInt(values.toString())) : values));
					// like
					if ("like".equals(operator))
						c.add(Restrictions.like(key, values));

				} else {
					c.add(Restrictions.or(Restrictions.eq(key, null), Property.forName(key).isNull(),
							Restrictions.eq(key, "")));
				}
			}

			// Projections.rowCount() 来取得总记录数
			rows = c.setProjection(Projections.rowCount()).uniqueResult().toString();
			return Double.parseDouble(rows);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

	}

	// 获取该表多条件记录总条数{object表，keys字段，values字段对应值}
	@Override
	public double queryRecordNumByAND(Object object, String[] keys, Object[] values, String[] operator) {

		String rows = null;
		try {

			Criteria c = this.getCurrentSession().createCriteria(object.getClass());

			if (keys.length > 0) {
				Integer i = 0;
				for (String key : keys) {
					if (values[i] != null) {
						// =
						if ("=".equals(operator[i])) {
							c.add(Restrictions.eq(key, (values[i] instanceof Integer)
									? (Integer.parseInt(values[i].toString())) : values[i]));
							i++;
							continue;
						}
						// ＞
						if (">".equals(operator[i])) {
							c.add(Restrictions.gt(key, (values[i] instanceof Integer)
									? (Integer.parseInt(values[i].toString())) : values[i]));
							i++;
							continue;
						}
						// ＞＝
						if (">=".equals(operator[i])) {
							c.add(Restrictions.ge(key, (values[i] instanceof Integer)
									? (Integer.parseInt(values[i].toString())) : values[i]));
							i++;
							continue;
						}
						// ＜
						if ("<".equals(operator[i])) {
							c.add(Restrictions.lt(key, (values[i] instanceof Integer)
									? (Integer.parseInt(values[i].toString())) : values[i]));
							i++;
							continue;
						}
						// ＜＝
						if ("<=".equals(operator[i])) {
							c.add(Restrictions.le(key, (values[i] instanceof Integer)
									? (Integer.parseInt(values[i].toString())) : values[i]));
							i++;
							continue;
						}
						// like
						if ("like".equals(operator[i]))
							c.add(Restrictions.like(key, values[i]));
					} else {
						c.add(Restrictions.or(Restrictions.eq(key, null), Property.forName(key).isNull(),
								Restrictions.eq(key, "")));
					}
					i++;
				}

			}

			// Projections.rowCount() 来取得总记录数
			rows = c.setProjection(Projections.rowCount()).uniqueResult().toString();
			return Double.parseDouble(rows);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}

	}

	/**
	 * 
	 * YC 2017年8月3日 下午2:31:59
	 * <p>
	 * Title: query
	 * </p>
	 * <p>
	 * Description: 通过查询对象条件查询
	 * </p>
	 * 
	 * @param object
	 *            查询哪张表
	 * @param params
	 *            分页排序
	 * @return
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> query(Object object, PageParams params) throws Exception {

		Criteria c = this.getCurrentSession().createCriteria(object.getClass());
		// 判断是否分页
		if (params.getLimit() != -1) {
			c.setFirstResult(params.getOffset());
			c.setMaxResults(params.getLimit());
		}
		// 判断是否排序
		if (StringUtils.isNotBlank(params.getSidx()))
			c.addOrder(new Order(params.getSidx(), params.getOrder()));

		return c.list();

	}

	/**
	 * 
	 * YC 2017年8月3日 下午2:31:59
	 * <p>
	 * Title: query
	 * </p>
	 * <p>
	 * Description: 通过查询对象条件查询
	 * </p>
	 * 
	 * @param object
	 *            查询哪张表
	 * @param params
	 *            分页排序
	 * @param whereParams
	 *            查询条件
	 * @return
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Object> query(Object object, PageParams params, Map<String, Object> whereParams) throws Exception {

		Criteria c = this.getCurrentSession().createCriteria(object.getClass());
		for (Map.Entry<String, Object> entry : whereParams.entrySet()) {

			if (StringUtils.isNotBlank(entry.getKey())) {
				if (entry.getValue() instanceof Integer)
					c.add(Restrictions.eq(entry.getKey(), Integer.parseInt(entry.getValue().toString())));
				else
					c.add(Restrictions.eq(entry.getKey(), entry.getValue()));
			}
		}
		// 判断是否分页
		if (params.getLimit() != -1) {
			c.setFirstResult(params.getOffset());
			c.setMaxResults(params.getLimit());
		}
		// 判断是否排序
		if (StringUtils.isNotBlank(params.getSidx()))
			c.addOrder(new Order(params.getSidx(), params.getOrder()));

		return c.list();

	}

}
